﻿from typing import List
from enum import Enum
from core import Core
from memory import GlobalMemory
from cache import Cache
from tlb import MMU
from threading import Thread
from time import sleep
from sys import argv
import numpy as np
from numpy import ndarray, uint8, uint16, uint32, uint64, float32, float64
from typedef import *


class Processor:
    def __init__(self, memory: GlobalMemory):
        self.__memory = memory
        self.__cache: List[Cache] = [Cache(memory)]
        self.__tlb: List[MMU] = [MMU(memory)]
        self.__core: List[Core] = None
        self.__max_cores: int = 0
        self.__threads: List[Thread] = None
        self.__IO: IO = IO()

    def init(self, core_num: int):
        self.__max_cores = core_num
        self.__core = [Core(0, self.__memory, self.__cache[0], self.__tlb[0])]

    def __call__(self):
        self.__threads = [
            Thread(target=i.__call__, name=f"Core{i.id}", daemon=True) for i in self.__core]
        for i in self.__threads:
            i.start()
        for i in self.__threads:
            while i.is_alive():
                sleep(1e-5)


if __name__ == '__main__':
    memory = GlobalMemory(1024**2)
    with open(argv[1], 'rb') as f:
        data = f.read()
    data = np.frombuffer(data, dtype=uint8)
    memory[0] = data
    processor = Processor(memory)
    processor.init(1)
    processor()
